package com.dwxt.cdms.service;

import com.dwxt.cdms.applets.dto.IndexGraphDayResDTO;
import com.dwxt.cdms.applets.dto.IndexGraphResDTO;
import com.dwxt.cdms.applets.dto.IndexReqDTO;
import com.dwxt.cdms.base.Page;
import com.dwxt.cdms.constant.EquipCategory;
import com.dwxt.cdms.constant.ReceiveDataType;
import com.dwxt.cdms.dao.*;
import com.dwxt.cdms.dao.oufu.OuFuDataMapper;
import com.dwxt.cdms.dao.oufu.OuFuLocDataMapper;
import com.dwxt.cdms.entity.Customer;
import com.dwxt.cdms.entity.Equipment;
import com.dwxt.cdms.entity.EquipmentCustom;
import com.dwxt.cdms.entity.Warning;
import com.dwxt.cdms.entity.oufu.OuFuData;
import com.dwxt.cdms.entity.oufu.OuFuDataExample;
import com.dwxt.cdms.entity.oufu.OuFuLocData;
import com.dwxt.cdms.entity.oufu.OuFuLocDataExample;
import com.dwxt.cdms.entity.vo.OuFuDataVO;
import com.dwxt.cdms.entity.vo.OuFuLocDataVO;
import com.dwxt.cdms.util.ListUtil;
import com.dwxt.cdms.util.RedisUtil;
import com.dwxt.cdms.util.ReqUtils;
import com.dwxt.cdms.util.UtilDao.Point;
import com.dwxt.cdms.view.wristwatch.NewSleepDataView;
import com.dwxt.cdms.vo.SelcetHeartCardVo;
import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.constant.VariableConstants;
import com.dwxt.common.util.DateUtils;
import com.dwxt.common.util.IDUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OuFuService {
    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    @Autowired
    private OuFuDataMapper ouFuDataMapper;

    @Autowired
    private OuFuLocDataMapper ouFuLocDataMapper;

    @Autowired
    private EquipmentCustomService equipmentCustomService;

    @Autowired
    private HealthService healthService;

    @Autowired
    private WarningMapper warningMapper;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private ElectronicFenceService electronicFenceService;

    @Autowired
    private EquipmentMapper equipmentMapper;

    @Autowired
    private OuFuDataWatchMapper watchMapper;

    @Autowired
    private OuFuLocDataWatchMapper locDataWatchMapper;

    @Autowired
    private StationService stationService;

    @Autowired
    private OuFuDataCardMapper cardMapper;

    @Autowired
    private OuFuDataBandSleepMapper bandSleepMapper;

    @Transactional
    public BaseResult receiveData(HttpServletRequest request) throws ParseException {
        //把参数转换为JSONObject
        JSONObject para = ReqUtils.getParaJsonObject(request);
        if (para.isEmpty()) {
            return BaseResult.ok();
        }
        log.info("oufu数据：{}", para.toString());
        //设置属性
        setPara(para);
        String type = para.getString("type");
        OuFuData ouFuData = (OuFuData) JSONObject.toBean(para, OuFuData.class);
        EquipmentCustom equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(ouFuData.getImei());
        if (equipmentCustom == null) {
            return BaseResult.ok();
        }
        //舍弃掉手环血压数据
        if ("8".equals(ouFuData.getType())) {
            Equipment equipment = equipmentMapper.selectEquipmentBySerialNumber(ouFuData.getImei(), "");
            if (EquipCategory.ZNSH.equals(equipment.getCategory())) {
                return BaseResult.ok();
            }
        }
        if (ReceiveDataType.notNeedWarnList.contains(type)) {
            // 6.24 如果是体温预警 ， 判断体温的值 ， 如果是未佩戴情况下 ， 不做预警处理。
            if (ReceiveDataType.TEMPERATURE.equals(type) && Double.parseDouble(ouFuData.getBodyTemperature()) < 20) {
                return null;
            }
            // 6.24 后续，判断会员身体状态是否为生病发烧，如果是发烧状态 并且体温相差不大，则判断延长报警间隔时间，可采用redis缓存
            //ouFuDataMapper.insertSelective(ouFuData);
            insertOuFuData(ouFuData);
        } else if (ReceiveDataType.needWarnList.contains(type)) {
            insertOuFuData(ouFuData);
            if (para.containsKey("customerId")) {
                healthService.judgeIsNormalAndInsertRecord(ouFuData);
            }
        } else if (ReceiveDataType.warnList.contains(type) && para.containsKey("content")) {
            Warning warning = (Warning) JSONObject.toBean(para, Warning.class);
            log.debug("warning" + warning.toString());
            warning.setId(IDUtils.genItemId());
            warning.setState(VariableConstants.STRING_CONSTANT_0);
            // 6.24 设置报警时间 ， 防止连续推送相同信息
            String s = RedisUtil.get(warning.getCustomerId().toString() + warning.getContent(), String.class);
            if (s != null) {
                return null;
            }
            RedisUtil.set(warning.getCustomerId().toString() + warning.getContent(), "相同预警", 20L);
            //warningMapper.insertSelective(warning);
            insertOuFuDataWarning(warning);
        } else if (ReceiveDataType.locList.contains(type)) {
            OuFuLocData ouFuLocData = (OuFuLocData) JSONObject.toBean(para, OuFuLocData.class);
            //ouFuLocDataMapper.insertSelective(ouFuLocData);
            insertOuFuLocData(ouFuLocData);
            //判断是否在电子围栏内
            equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(ouFuLocData.getImei());
            if (para.get("latitude") != null && para.get("longitude") != null) {
                boolean warning = electronicFenceService.isWarning(new Point(Double.parseDouble(para.get("longitude").toString()), Double.parseDouble(para.get("latitude").toString())), equipmentCustom.getCustomerId());
                if (warning) {
                    Warning locWarning = new Warning();
                    locWarning.setId(IDUtils.genItemId());
                    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateStr = dateFormat.format(new Date());
                    locWarning.setWarningTime(dateStr);
                    locWarning.setContent("电子围栏报警，请您注意！");
                    locWarning.setCustomerId(equipmentCustom.getCustomerId());
                    locWarning.setType("1");
                    locWarning.setState("0");
                    locWarning.setImei(ouFuLocData.getImei());
                    insertOuFuDataWarning(locWarning);
                }
            }
        } else {
            log.info("oufu数据：{}", para.toString());
        }
        return BaseResult.ok();
    }

    public void insertOuFuData(OuFuData ouFuData) {
        Equipment equipment = equipmentMapper.selectEquipmentBySerialNumber(ouFuData.getImei(), "");
        if (equipment != null) {
            if (EquipCategory.ZNSB.equals(equipment.getCategory())) {
                //欧孚M99智能手表
                watchMapper.insertSelective(ouFuData);
            } else {
                //欧孚手环
                if (!"8".equals(ouFuData.getType())) {
                    ouFuDataMapper.insertSelective(ouFuData);
                    if (ReceiveDataType.SLEEP.equals(ouFuData.getType())) {
                        bandSleepMapper.insertSelective(ouFuData);
                    }
                }
            }
        }
    }

    public void insertOuFuDataWarning(Warning warning) {
        Equipment equipmentObj = new Equipment();
        equipmentObj.setSerialNumber(warning.getImei());
        equipmentObj.setIsDelete("0");
        Equipment equipment = equipmentMapper.selectOne(equipmentObj);
        if (equipment != null) {
            warning.setCategory(equipment.getCategory());
            warningMapper.insertSelective(warning);
        }
    }

    public void insertOuFuLocData(OuFuLocData ouFuLocData) {
        Equipment equipmentObj = new Equipment();
        equipmentObj.setSerialNumber(ouFuLocData.getImei());
        equipmentObj.setIsDelete("0");
        Equipment equipment = equipmentMapper.selectOne(equipmentObj);
        if (equipment == null) {
            return;
        }
        //如果是胸卡，插入胸卡的查询列表
        if (equipment.getCategory().equals(EquipCategory.XK)) {
            OuFuLocDataExample ouFuLocDataExample = new OuFuLocDataExample();
            OuFuLocDataExample.Criteria criteria = ouFuLocDataExample.createCriteria();
            criteria.andImeiEqualTo(ouFuLocData.getImei());
            //删除旧数据并新增
            cardMapper.deleteByExample(ouFuLocDataExample);
            cardMapper.insertSelective(ouFuLocData);
        }
        if (equipment != null) {
            if (EquipCategory.ZNSB.equals(equipment.getCategory())) {
                //欧孚M99智能手表
                locDataWatchMapper.insertSelective(ouFuLocData);
            } else {
                //欧孚手环和胸卡
                ouFuLocDataMapper.insertSelective(ouFuLocData);
            }
        }
    }

    private void setPara(JSONObject para) throws ParseException {
        String imei = "";
        if (para.containsKey("IMEI")) {
            imei = para.getString("IMEI");
            para.put("imei", imei);
            para.remove("IMEI");
        }
        //设置checkTime
        setCheckTime(para);
        //设置customerId
        EquipmentCustom eq = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(imei);
        if (Optional.ofNullable(eq).map(EquipmentCustom::getCustomerId).isPresent()) {
            para.put("customerId", eq.getCustomerId());
        }
        //设置content
        if (para.containsKey("AlertInfo")) {
            String type = para.getString("type");
            //String alertInfo = para.getString("AlertInfo");
            para.remove("AlertInfo");
            StringBuilder sb = new StringBuilder();
            Optional.ofNullable(eq).map(eqcu -> customerService.selectCustomerById(eqcu.getCustomerId())).ifPresent(customer -> {
                sb.append("【").append(customer.getName()).append("】");
                switch (type) {
                    case ReceiveDataType.LOW_ELECTRICITY:
                        sb.append("低电量报警，请您注意！");
                        break;
                    case ReceiveDataType.SOS:
                        sb.append("SOS报警，请您注意！");
                        break;
                    case ReceiveDataType.SOS_CANCEL:
                        sb.append("SOS报警取消，请您注意！");
                        break;
                    case ReceiveDataType.SHUT_DOWN:
                        sb.append("关机报警，请您注意！");
                        break;
                    case ReceiveDataType.REMOVE:
                        sb.append("摘除报警,请您注意！");
                        break;
                }
                para.put("content", sb.toString());
            });
        }
        //设置维度
        if (para.containsKey("latStr")) {
            String latStr = para.getString("latStr");
            if ("0".equals(latStr)) {
                throw new ParseException("纬度获取失败", 99);
            }
            para.remove("latStr");
            para.put("latitude", latStr);
        }
        if (para.containsKey("Latitude")) {
            String latitude = para.getString("Latitude");
            if ("0".equals(latitude)) {
                throw new ParseException("纬度获取失败", 99);
            }
            para.remove("Latitude");
            para.put("latitude", latitude);
        }
        //经度
        if (para.containsKey("lngStr")) {
            String lngStr = para.getString("lngStr");
            if ("0".equals(lngStr)) {
                throw new ParseException("经度获取失败", 99);
            }
            para.remove("lngStr");
            para.put("longitude", lngStr);
        }
        if (para.containsKey("Longitude")) {
            String Longitude = para.getString("Longitude");
            if ("0".equals(Longitude)) {
                throw new ParseException("经度获取失败", 99);
            }
            para.remove("Longitude");
            para.put("longitude", Longitude);
        }
        //速度
        if (para.containsKey("speedStr")) {
            String speedStr = para.getString("speedStr");
            para.remove("speedStr");
            para.put("speed", speedStr);
        }
        //BT info
        if (para.containsKey("BTInfo")) {
            String BTInfo = para.getString("BTInfo");
            para.remove("BTInfo");
            para.put("btinfo", BTInfo);
        }
        //Lac
        if (para.containsKey("Lac")) {
            String Lac = para.getString("Lac");
            para.remove("Lac");
            para.put("lac", Lac);
        }
        //Db
        if (para.containsKey("Db")) {
            String Db = para.getString("Db");
            para.remove("Db");
            para.put("db", Db);
        }
    }

    private void setCheckTime(JSONObject para) throws ParseException {
        String format;
        if (para.containsKey("BTUtcTime")) {
            String btUtcTime = para.getString("BTUtcTime");
            para.remove("BTUtcTime");
            if (btUtcTime.contains("/")) {
                format = "yyyy/MM/dd HH:mm:ss";
            } else {
                format = "yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat(format);
            Date date = dateFormat.parse(btUtcTime);
            String checkTime = dateFormat.format(new Date(date.getTime() + (long) 8 * 60 * 60 * 1000));
            //数据
            para.put("checkTime", checkTime);
            //预警
            para.put("warningTime", checkTime);
        } else if (para.containsKey("timeStr")) {
            String timeStr = para.getString("timeStr");
            para.remove("timeStr");
            para.put("checkTime", timeStr);
        }
    }


    public BaseResult pageGroup(Page page, String name, String type, String category) {
        Integer stationId = stationService.getLoginUserStation();
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        if (ReceiveDataType.locList.contains(type)) {
            List<OuFuLocDataVO> ouFuLocDataVOList;
            if (EquipCategory.ZNSB.equals(category)) {
                ouFuLocDataVOList = locDataWatchMapper.selectGroup(name, type,stationId);
            } else {
                ouFuLocDataVOList = ouFuLocDataMapper.selectGroup(name, type,stationId);
            }
            ouFuLocDataVOList.forEach(ouFuLocDataVO -> {
                //围栏设置
                Optional.ofNullable(electronicFenceService.selectFenceByCustomerId(ouFuLocDataVO.getCustomerId()))
                        .ifPresent(electronicFence -> {
                            ouFuLocDataVO.setIsEnabled(electronicFence.getStatus());
                            ouFuLocDataVO.setElectronicArea(electronicFence.getElectronicArea());
                            ouFuLocDataVO.setElectronicAreaDouble(electronicFence.getElectronicAreaDouble());
                            ouFuLocDataVO.setElectronicFenceId(electronicFence.getId());
                        });
            });
            //PageInfo pageInfo = new PageInfo(ouFuLocDataVOList);
            return BaseResult.ok(new PageInfo(ouFuLocDataVOList));
        } else {
            List<OuFuDataVO> ouFuDataVOList;
            if (!ReceiveDataType.SLEEP.equalsIgnoreCase(type)) {
                if (EquipCategory.ZNSB.equals(category)) {
                    //欧孚m99手表
                    ouFuDataVOList = watchMapper.selectGroup(name, type,stationId);
                } else {
                    //欧孚手环
                    ouFuDataVOList = ouFuDataMapper.selectGroup(name, type,stationId);
                }
                return BaseResult.ok(new PageInfo(ouFuDataVOList));
            } else {
                //睡眠单独处理
                return BaseResult.ok(getSleepData(name));
            }
        }
    }

    /**
     * 定位数据列表查询
     */

    public BaseResult pageGroup2(SelcetHeartCardVo selcetHeartCardVo) {
        PageHelper.startPage(selcetHeartCardVo.getPageNum(), selcetHeartCardVo.getPageSize());
        if (ReceiveDataType.locList.contains(selcetHeartCardVo.getType())) {
            List<OuFuLocDataVO> ouFuLocDataVOList = ouFuLocDataMapper.selectGroupByHeartCard(selcetHeartCardVo.getName(), selcetHeartCardVo.getType());
            ouFuLocDataVOList.forEach(ouFuLocDataVO -> {
                //围栏设置
                Optional.ofNullable(electronicFenceService.selectFenceByCustomerId(ouFuLocDataVO.getCustomerId()))
                        .ifPresent(electronicFence -> {
                            ouFuLocDataVO.setIsEnabled(electronicFence.getStatus());
                            ouFuLocDataVO.setElectronicArea(electronicFence.getElectronicArea());
                            ouFuLocDataVO.setElectronicAreaDouble(electronicFence.getElectronicAreaDouble());
                            ouFuLocDataVO.setElectronicFenceId(electronicFence.getId());
                        });
            });
            return BaseResult.ok(new PageInfo(ouFuLocDataVOList));
        } else {
            return BaseResult.build(StatusCode.SELECT_INFO_ISNOT_EXIST);
        }
    }

    private PageInfo getSleepData(String name) {
        List<Integer> customerIdList = ouFuDataMapper.selectCustomerIdsBySleepData(name);
        PageInfo pageInfo = new PageInfo(customerIdList);
        List<NewSleepDataView> list = new ArrayList<>();
        for (Integer customerId : customerIdList) {
            NewSleepDataView newSleepDataView = getNewSleepDataView(customerId);
            if (newSleepDataView != null) {
                list.add(newSleepDataView);
            }
        }
        //按测量时间降序排序
        list.sort((m1, m2) -> m2.getEndTime().compareTo(m1.getEndTime()));
//        List<NewSleepDataView> list = sleepDataMapper.selectSleepDataViewByCondition(selectWatchDataVo);
        pageInfo.setList(list);
        return pageInfo;
    }

    public NewSleepDataView getNewSleepDataView(Integer customerId) {
        List<OuFuData> fuDataList = selectSleepByCustomerId(customerId);
        if (fuDataList.size() <= 0) {
            return null;
        }
        OuFuData ouFuData = fuDataList.get(0);
        int year = getYearMonthDay(ouFuData.getEndTime(), 1);
        int month = getYearMonthDay(ouFuData.getEndTime(), 2);
        int day = getYearMonthDay(ouFuData.getEndTime(), 3);
        String startTime;
        if (getYearMonthDay(ouFuData.getEndTime(), 4) > 12) {
            startTime = year + "/" + month + "/" + day + " 12:00:00";
        } else {
            if (day == 1) {
                Calendar cale = Calendar.getInstance();
                cale.set(Calendar.DAY_OF_MONTH, 0);
                int i = cale.get(Calendar.DAY_OF_MONTH);
                startTime = year + "/" + (month - 1) + "/" + i + " 12:00:00";
            } else {
                startTime = year + "/" + month + "/" + (day - 1) + " 12:00:00";
            }
        }
        List<OuFuData> ouFuDataList = selectSleepRangeRecord(customerId, startTime, ouFuData.getEndTime());
        if (ouFuDataList.size() <= 0) {
            return null;
        }
        return handle(ouFuDataList);
    }

    private NewSleepDataView handle(List<OuFuData> ouFuDataList) {
        if (ouFuDataList == null || ouFuDataList.size() <= 0) {
            return null;
        }
        int sleepingTime1 = 0;
        int sleepingTime2 = 0;
        int sleepingTime3 = 0;
        for (OuFuData ouFuData : ouFuDataList) {
            //浅睡眠
            if (ouFuData.getSleepType() == 2) {
                sleepingTime1 += ouFuData.getMinute();
            } else if (ouFuData.getSleepType() == 1) {
                //深睡眠
                sleepingTime2 += ouFuData.getMinute();
            } else if (ouFuData.getSleepType() == 3) {
                //清醒
                sleepingTime3 += ouFuData.getMinute();
            }
        }
        Customer customer = customerService.selectCustomerById(ouFuDataList.get(0).getCustomerId());
        NewSleepDataView newSleepDataView = new NewSleepDataView();
        newSleepDataView.setBeginTime(ouFuDataList.get(ouFuDataList.size() - 1).getStartTime());
        newSleepDataView.setCheckTime(newSleepDataView.getBeginTime());
        newSleepDataView.setEndTime(ouFuDataList.get(0).getEndTime());
        newSleepDataView.setSleepingTimeRange(sleepingTime1 + sleepingTime2 + sleepingTime3 + "分钟");
        newSleepDataView.setSleepingTime1(sleepingTime1 + "分钟");
        newSleepDataView.setSleepingTime2(sleepingTime2 + "分钟");
        newSleepDataView.setSleepingTime3(sleepingTime3 + "分钟");
        newSleepDataView.setSleepingTime4("0分钟");
        newSleepDataView.setCustomerType(customer.getCustomerType());
        newSleepDataView.setTheOldType(customer.getTheOldType());
        newSleepDataView.setServiceType(customer.getServiceType());
        newSleepDataView.setName(customer.getName());
        newSleepDataView.setCustomerId(customer.getId());
        //newSleepDataView.setCreateTime();
        return newSleepDataView;
    }

    private List<OuFuData> selectRangeRecord(Integer customerId, String startTime, String endTime) {
        OuFuDataExample example = new OuFuDataExample();
        example.setOrderByClause("create_time desc");
        example.createCriteria().andCustomerIdEqualTo(customerId).andTypeEqualTo(ReceiveDataType.SLEEP)
                .andStartTimeGreaterThan(startTime).andEndTimeLessThanOrEqualTo(endTime);
        return ouFuDataMapper.selectByExample(example);
    }

    private List<OuFuData> selectSleepRangeRecord(Integer customerId, String startTime, String endTime) {
        return ouFuDataMapper.selectSleepRangeRecord(customerId, ReceiveDataType.SLEEP, startTime, endTime);
    }

    private int getYearMonthDay(String endTime, int type) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(format.parse(endTime));
            if (type == 1) {
                return calendar.get(Calendar.YEAR);
            } else if (type == 2) {
                return calendar.get(Calendar.MONTH) + 1;
            } else if (type == 3) {
                return calendar.get(Calendar.DAY_OF_MONTH);
            } else if (type == 4) {
                return calendar.get(Calendar.HOUR_OF_DAY);
            } else {
                throw new RuntimeException("类型错误");
            }
        } catch (ParseException e) {
            throw new RuntimeException();
        }
    }

    private List<OuFuData> selectSleepByCustomerId(Integer customerId) {
        OuFuDataExample example = new OuFuDataExample();
        example.setOrderByClause("create_time desc");
        example.createCriteria().andCustomerIdEqualTo(customerId).andTypeEqualTo(ReceiveDataType.SLEEP);
        List<OuFuData> ouFuDataList = ouFuDataMapper.selectByExample(example);
        return ouFuDataList;
    }

    public BaseResult page(Page page, Integer customerId, String type, String category) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List list;
        if (!ReceiveDataType.locList.contains(type)) {
            if (EquipCategory.ZNSB.equals(category)) {
                //手表
                list = watchMapper.selectPage(customerId, type);
            } else {
                //手环
                list = ouFuDataMapper.selectPage(customerId, type);
            }
        } else {
            if (EquipCategory.ZNSB.equals(category)) {
                //手表
                list = locDataWatchMapper.selectPage(customerId, type);
            } else {
                //手环
                list = ouFuLocDataMapper.selectPage(customerId, type);
            }

        }

        return BaseResult.ok(new PageInfo<>(list));
    }

    public BaseResult pageSleep(Page page, Integer customerId) {
        //获取客户 睡眠记录
        List<NewSleepDataView> list = getNewSleepDataViews(customerId);
        List<String> pageList = ListUtil.pageBySubList(list, page.getPageSize(), page.getPageNum());
        Map res = new HashMap();
        res.put("list", pageList);
        res.put("pageNum", page.getPageNum());
        res.put("pageSize", page.getPageSize());
        res.put("total", list.size());
        return BaseResult.ok(res);
    }

    public List<NewSleepDataView> getNewSleepDataViews(Integer customerId) {
        List<OuFuData> ouFuDataList = selectSleepByCustomerId(customerId);
        //OuFuData fuData = ouFuDataList.get(0);
        List<NewSleepDataView> list = new ArrayList<>();
        while (ouFuDataList.size() > 0) {
            ouFuDataList = handle(ouFuDataList, customerId, list);
        }
        return list;
    }

    private List<OuFuData> handle(List<OuFuData> ouFuDataList, Integer customerId, List<NewSleepDataView> list) {
        //NewSleepDataView handle = null;
        String startTime;
        OuFuData ouFuData = ouFuDataList.get(0);
        String endTime = ouFuData.getEndTime();
        int year = getYearMonthDay(endTime, 1);
        int month = getYearMonthDay(endTime, 2);
        int day = getYearMonthDay(endTime, 3);
        if (getYearMonthDay(endTime, 4) > 12) {
            startTime = year + "/" + month + "/" + day + " 12:00:00";
        } else {
            startTime = year + "/" + month + "/" + (day - 1) + " 12:00:00";
        }
        List<OuFuData> rangList = selectSleepRangeRecord(customerId, startTime, endTime);
        NewSleepDataView sleepDataView = handle(rangList);
        list.add(sleepDataView);
        return ouFuDataList.stream().filter(ouFu -> !DateUtils.after(format, ouFu.getEndTime(), startTime)).collect(Collectors.toList());
    }

    public OuFuData selectLastDataByType(Integer customerId, String type) {
        OuFuDataExample example = new OuFuDataExample();
        example.setOrderByClause("create_time desc");
        example.createCriteria().andCustomerIdEqualTo(customerId).andTypeEqualTo(type);
        List<OuFuData> ouFuDataList = ouFuDataMapper.selectByExample(example);
        return ouFuDataList.size() > 0 ? ouFuDataList.get(0) : null;
    }

    public OuFuData selectLastDataByType(Integer customerId, String type, String category) {
        OuFuDataExample example = new OuFuDataExample();
        example.setOrderByClause("create_time desc");
        example.createCriteria().andCustomerIdEqualTo(customerId).andTypeEqualTo(type);
        List<OuFuData> ouFuDataList = new ArrayList<>();
        if (EquipCategory.ZNSB.equals(category)) {
            //M99手表
            ouFuDataList = watchMapper.selectByExample(example);
        } else {

            ouFuDataList = ouFuDataMapper.selectByExample(example);
        }
        return ouFuDataList.size() > 0 ? ouFuDataList.get(0) : null;
    }

    public List<OuFuData> selectOuFuGraph(Integer customerId, String type) {
        return ouFuDataMapper.selectOuFuGraph(customerId, type);
    }

    public List<IndexGraphResDTO> selectGraphWithDate(IndexReqDTO indexReqDTO) {
        return ouFuDataMapper.selectGraphWithDate(indexReqDTO);
    }

    public List<IndexGraphDayResDTO> selectGraphWithDay(IndexReqDTO indexReqDTO) {
        return ouFuDataMapper.selectGraphWithDay(indexReqDTO);
    }

    public List<IndexGraphResDTO> selectStepDateEveryDay(IndexReqDTO indexReqDTO) {
        return ouFuDataMapper.selectStepDateEveryDay(indexReqDTO);
    }

    public List<OuFuLocData> selectLocDataListByCustomerIdAndTime(Integer customerId, String startTime, String endTime) {
        return ouFuLocDataMapper.selectLocDataListByCustomerIdAndTime(customerId, startTime, endTime);
    }

    public List<OuFuLocData> selectAllLocDataListByCustomerIdAndTime(Integer customerId, String startTime, String endTime) {
        return ouFuLocDataMapper.selectAllLocDataListByCustomerIdAndTime(customerId, startTime, endTime);
    }

    public List<IndexGraphDayResDTO> selectTempDateEveryDay(IndexReqDTO indexReqDTO) {
        return ouFuDataMapper.selectTempDateEveryDay(indexReqDTO);
    }

    public List<OuFuData> selectCustomerOufu(String customerId, Integer scope, String type) {
        return ouFuDataMapper.selectCustomerOufu(customerId, scope, type);
    }

    public BaseResult selectCustomerOufuData(String customerId, Integer scope, String type) {
        List<OuFuData> ouFuDataList = ouFuDataMapper.selectCustomerOufu(customerId, scope, type);
        if (ReceiveDataType.SLEEP.equalsIgnoreCase(type) && !scope.equals(1)) {
            List<NewSleepDataView> list = new ArrayList<>();
            while (ouFuDataList.size() > 0) {
                ouFuDataList = handle(ouFuDataList, Integer.valueOf(customerId), list);
            }
            return BaseResult.ok(list);
        }
        return BaseResult.ok(ouFuDataList);
    }
    public List<OuFuLocData> selectCardLocDataListByImeiAndTime(Integer customerId,String imei, String startTime, String endTime) {
        return ouFuLocDataMapper.selectCardLocDataListByImeiAndTime(customerId,imei, startTime, endTime);
    }

    public List<OuFuLocData> selectWatchLocDataListByImeiAndTime(Integer customerId, String startTime, String endTime) {
        return locDataWatchMapper.selectWatchLocDataListByImeiAndTime(customerId, startTime, endTime);
    }

    public BaseResult receiveDataZT(HttpServletRequest request) throws ParseException {
        //把参数转换为JSONObject
        JSONObject para = ReqUtils.getParaJsonObject(request);
        if (para.isEmpty()) {
            return BaseResult.ok();
        }
        log.info("中台数据：{}", para.toString());
        //设置属性
        setPara(para);
        String type = para.getString("type");
        OuFuData ouFuData = (OuFuData) JSONObject.toBean(para, OuFuData.class);
        EquipmentCustom equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(ouFuData.getImei());
        if (equipmentCustom == null) {
            return BaseResult.ok();
        }
        ouFuData.setSource("1");
        //舍弃掉手环血压数据
        if ("8".equals(ouFuData.getType())) {
            Equipment equipment = equipmentMapper.selectEquipmentBySerialNumber(ouFuData.getImei(), "");
            if (EquipCategory.ZNSH.equals(equipment.getCategory())) {
                return BaseResult.ok();
            }
        }
        if (ReceiveDataType.notNeedWarnList.contains(type)) {
            // 6.24 如果是体温预警 ， 判断体温的值 ， 如果是未佩戴情况下 ， 不做预警处理。
            if (ReceiveDataType.TEMPERATURE.equals(type) && Double.parseDouble(ouFuData.getBodyTemperature()) < 20) {
                return null;
            }
            // 6.24 后续，判断会员身体状态是否为生病发烧，如果是发烧状态 并且体温相差不大，则判断延长报警间隔时间，可采用redis缓存
            //ouFuDataMapper.insertSelective(ouFuData);
            insertOuFuData(ouFuData);
        } else if (ReceiveDataType.needWarnList.contains(type)) {
            insertOuFuData(ouFuData);
            if (para.containsKey("customerId")) {
                healthService.judgeIsNormalAndInsertRecord(ouFuData);
            }
        } else if (ReceiveDataType.warnList.contains(type) && para.containsKey("content")) {
            Warning warning = (Warning) JSONObject.toBean(para, Warning.class);
            log.debug("warning" + warning.toString());
            warning.setId(IDUtils.genItemId());
            warning.setState(VariableConstants.STRING_CONSTANT_0);
            // 6.24 设置报警时间 ， 防止连续推送相同信息
            String s = RedisUtil.get(warning.getCustomerId().toString() + warning.getContent(), String.class);
            if (s != null) {
                return null;
            }
            RedisUtil.set(warning.getCustomerId().toString() + warning.getContent(), "相同预警", 20L);
            //warningMapper.insertSelective(warning);
            insertOuFuDataWarning(warning);
        } else if (ReceiveDataType.locList.contains(type)) {
            OuFuLocData ouFuLocData = (OuFuLocData) JSONObject.toBean(para, OuFuLocData.class);
            //ouFuLocDataMapper.insertSelective(ouFuLocData);
            insertOuFuLocData(ouFuLocData);
            //判断是否在电子围栏内
            if (para.get("latitude") != null && para.get("longitude") != null) {
                boolean warning = electronicFenceService.isWarning(new Point(Double.parseDouble(para.get("longitude").toString()), Double.parseDouble(para.get("latitude").toString())), equipmentCustom.getCustomerId());
                if (warning) {
                    Warning locWarning = new Warning();
                    locWarning.setId(IDUtils.genItemId());
                    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateStr = dateFormat.format(new Date());
                    locWarning.setWarningTime(dateStr);
                    locWarning.setContent("电子围栏报警，请您注意！");
                    locWarning.setCustomerId(equipmentCustom.getCustomerId());
                    locWarning.setType("1");
                    locWarning.setState("0");
                    locWarning.setImei(ouFuLocData.getImei());
                    insertOuFuDataWarning(locWarning);
                }
            }
        } else {
            log.info("oufu数据：{}", para.toString());
        }
        return BaseResult.ok();
    }

}

